package com.example.service;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.example.common.enums.OrderStatus;
import com.example.common.enums.ResultCodeEnum;
import com.example.common.enums.RoleEnum;
import com.example.entity.*;
import com.example.exception.CustomException;
import com.example.mapper.OrdersMapper;
import com.example.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 订单信息业务处理
 **/
@Service
public class OrdersService {

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private CertificationService certificationService;

    @Resource
    private AddressService addressService;

    @Resource
    private UserService userService;

    @Resource
    private RecordsService recordsService;

    /**
     * 新增
     */
    public void add(Orders orders) {
        Account currentUser = TokenUtils.getCurrentUser();
        User user = userService.selectById(currentUser.getId());
        BigDecimal account = user.getAccount();
        if (orders.getPrice() > account.doubleValue()) {
            throw new CustomException(ResultCodeEnum.ACCOUNT_LIMIT);
        }
        user.setAccount(user.getAccount().subtract(BigDecimal.valueOf(orders.getPrice())));
        userService.updateById(user);

        orders.setUserId(currentUser.getId());
        orders.setOrderNo(IdUtil.getSnowflakeNextIdStr());
        orders.setTime(DateUtil.now());
        orders.setStatus(OrderStatus.NO_ACCEPT.getValue());
        ordersMapper.insert(orders);

        recordsService.record(BigDecimal.valueOf(orders.getPrice()), orders.getName() + "订单", "支出");
    }

    /**
     * 删除
     */
    public void deleteById(Integer id) {
        ordersMapper.deleteById(id);
    }

    /**
     * 批量删除
     */
    public void deleteBatch(List<Integer> ids) {
        for (Integer id : ids) {
            ordersMapper.deleteById(id);
        }
    }

    /**
     * 修改
     */
    @Transactional
    public void updateById(Orders orders) {
        if (OrderStatus.NO_COMMENT.getValue().equals(orders.getStatus())) {  // 已送达  打钱给骑手
            Integer acceptId = orders.getAcceptId();
            User user = userService.selectById(acceptId);
            user.setAccount(user.getAccount().add(BigDecimal.valueOf(orders.getPrice())));
            userService.updateById(user);

            // 记录骑手收支
            Records records = new Records();
            records.setUserId(acceptId);
            records.setTime(DateUtil.now());
            records.setMoney(BigDecimal.valueOf(orders.getPrice()));
            records.setType("骑手");
            records.setContent(orders.getName() + "订单");
            recordsService.add(records);
        }
        ordersMapper.updateById(orders);
    }

    /**
     * 根据ID查询
     */
    public Orders selectById(Integer id) {
        Orders orders = ordersMapper.selectById(id);
        Address address = addressService.selectById(orders.getAddressId());
        orders.setAddress(address);
        Address targetAddress = addressService.selectById(orders.getTargetId());
        orders.setTargetAddress(targetAddress);

        if (orders.getAcceptId() != null) {
            Certification certification = certificationService.selectByUserId(orders.getAcceptId());
            orders.setAcceptUser(certification);
        }
        return orders;
    }

    /**
     * 查询所有
     */
    public List<Orders> selectAll(Orders orders) {
        List<Orders> ordersList = ordersMapper.selectAll(orders);
        for (Orders o : ordersList) {
            String time = o.getTime();
            long between = DateUtil.between(DateUtil.parseDateTime(time), new Date(), DateUnit.MINUTE);
            o.setMinutes(between);
        }
        return ordersList;
    }

    /**
     * 分页查询
     */
    public PageInfo<Orders> selectPage(Orders orders, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Orders> list = ordersMapper.selectAll(orders);
        return PageInfo.of(list);
    }

    public void accept(Orders orders) {
        Integer ordersId = orders.getId();
        orders = selectById(ordersId);
        if (!OrderStatus.NO_ACCEPT.getValue().equals(orders.getStatus())) {
            throw new CustomException(ResultCodeEnum.ORDERS_STATUS_ERROR);
        }
        Account currentUser = TokenUtils.getCurrentUser();
        if (currentUser.getId().equals(orders.getUserId())) {  // 自己没法接单
            throw new CustomException(ResultCodeEnum.ACCEPT_ERROR);
        }
        Certification certification = certificationService.selectByUserId(currentUser.getId());
        if (RoleEnum.USER.name().equals(currentUser.getRole()) && (certification == null || !"通过".equals(certification.getStatus()))) {
            throw new CustomException(ResultCodeEnum.ORDERS_AUTH_ERROR);
        }
        orders.setAcceptId(currentUser.getId());
        orders.setAcceptTime(DateUtil.now());
        orders.setStatus(OrderStatus.NO_ARRIVE.getValue());
        this.updateById(orders);
    }
}